package com.quanyan.ic.video.http.interceptor;

import com.alibaba.fastjson.JSON;
import com.quanyan.ic.common.spring.SpringUtil;
import com.quanyan.ic.middleware.mq.rocketmq.producer.SendCallbackListener;
import com.quanyan.ic.video.model.hik8710.Hik8710EventAlarm;
import com.quanyan.ic.video.mq.PlaceUnitAlarmProducer;
import com.quanyan.ic.video.websocket.AlarmWebSocketServer;
import com.quanyan.ic.video.websocket.transfer.MessageType;
import com.quanyan.ic.video.websocket.transfer.WebSocketMessage;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * Created by zhuo.shi on 2017/8/19.
 * <p/>
 * 发送MQ消息，提供给分析平台订阅
 */
@Aspect
@Component
public class AlarmAddOrUpdateInterceptor {

    private static Logger logger = LoggerFactory.getLogger(AlarmAddOrUpdateInterceptor.class);

    @Autowired
    PlaceUnitAlarmProducer placeUnitAlarmProducer;

    @Pointcut("execution(* com.quanyan.ic.video..PlaceUnitAlarmService.addOrUpdateAlarm*(..))")
    public void alarmChanged() {
    }

    @Around(value = "alarmChanged()")
    public Object alarmProcess(ProceedingJoinPoint poj) throws Throwable {
        try {
            final Object result = poj.proceed();
            if (result == null) return result;
            placeUnitAlarmProducer.asyncSend(String.valueOf(result.hashCode()), JSON.toJSONString(result).getBytes(),
                    new SendCallbackListener() {
                        @Override
                        public void onSuccess(String sendResult) {
                            logger.info("send alarm --> MQ success, {}, {}", JSON.toJSONString(result), sendResult);
                        }
                        @Override
                        public void onException(Throwable e) {
                            logger.info("send alarm --> MQ failed, {}, {} ", JSON.toJSONString(result), e.getMessage());
                        }
                    });
            final Hik8710EventAlarm alarm = JSON.parseObject(JSON.toJSONString(result), Hik8710EventAlarm.class);
            Channel session = SpringUtil.getBean(AlarmWebSocketServer.class).getSession(String.valueOf(alarm.getPlaceId()));
            if (session == null || !session.isActive()) {
                logger.warn("place {} website offline", alarm.getPlaceId());
                return result;
            }
            WebSocketMessage<Hik8710EventAlarm> alarmMsg = new WebSocketMessage<>();
            alarmMsg.setType(MessageType.EVENT_ALARM);
            alarm.setEventId(null);
            alarm.setEventIds(null);
            alarmMsg.setData(alarm);
            ChannelFuture f = session.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(alarmMsg)));
            f.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture channelFuture) throws Exception {
                    logger.info("push alarm to place {} website, isDone={} isCancelled={} isSuccess={}, {}",
                            alarm.getPlaceId(),
                            channelFuture.isDone(), channelFuture.isCancelled(), channelFuture.isSuccess(),
                            JSON.toJSONString(alarm));
                }
            });
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
    }
}
